{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2b489ca8-dfbe-488a-9d85-ba1b15fb6fc6",
   "metadata": {},
   "source": [
    "# Numpy\n",
    "NumPy 是 Python 科学计算和数据分析的基础库之一，<br>\n",
    "几乎所有机器学习、数据分析、图像处理框架（如 pandas、TensorFlow、PyTorch）都建立在它之上。<br>\n",
    "大量用于 矩阵运算、线性代数、统计分析 的函数<br>\n",
    "为什么要用numpy呢？<br>\n",
    "C 语言级别的运算速度（比原生 Python 循环快 10~100 倍）<br>\n",
    "参考：https://www.runoob.com/numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c52903f9-dc5b-4c96-968a-4b7fcabe2b3d",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Python 版本耗时: 3.63987 秒\n",
      "NumPy 版本耗时: 0.42465 秒\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import time\n",
    "\n",
    "# 创建一个包含 1000 万个随机数的列表\n",
    "size = 100_000_000\n",
    "data_list = list(range(size))\n",
    "data_np = np.arange(size)\n",
    "\n",
    "# 1️⃣ 使用原生 Python 计算平方\n",
    "start = time.time()\n",
    "result_py = [x**2 for x in data_list]\n",
    "end = time.time()\n",
    "print(f\"Python 版本耗时: {end - start:.5f} 秒\")\n",
    "\n",
    "# 2️⃣ 使用 NumPy 计算平方\n",
    "start = time.time()\n",
    "result_np = data_np ** 2\n",
    "end = time.time()\n",
    "print(f\"NumPy 版本耗时: {end - start:.5f} 秒\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69221947-8753-47d8-ae1e-eb8695c19f8b",
   "metadata": {},
   "source": [
    "## 数组对象（ndarray）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7381ecf2-a911-4159-9561-cf79303bdf65",
   "metadata": {},
   "source": [
    "### 创建数组\n",
    "```python\n",
    "numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)\n",
    "```\n",
    "- object\t数组或嵌套的数列\n",
    "- dtype\t数组元素的数据类型，可选\n",
    "- copy\t对象是否需要复制，可选\n",
    "- order\t创建数组的样式，C为行方向，F为列方向，A为任意方向（默认）(内存中的摆放)\n",
    "- subok\t默认返回一个与基类类型一致的数组\n",
    "- ndmin\t指定生成数组的最小维度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "4e67d2f0-f8ee-41d5-9b1a-deac27e1a609",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4]\n",
      "<class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "#一维dimension\n",
    "import numpy as np\n",
    "a = np.array([1,2,3,4]) \n",
    "print (a)\n",
    "print(type(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "dc2a6f1d-800d-4c43-b772-66e33a0c4051",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2]\n",
      " [3 4]]\n"
     ]
    }
   ],
   "source": [
    "#多维\n",
    "import numpy as np \n",
    "a = np.array([[1,  2],  [3,  4]])  \n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67672dbd-3a0d-455f-895d-7a87bf6276a1",
   "metadata": {},
   "source": [
    "numpy.arange 函数创建数值范围并返回 ndarray 对象，函数格式如下：<br>\n",
    "\n",
    "```python\n",
    "numpy.arange(start, stop, step, dtype)\n",
    "```\n",
    "根据 start 与 stop 指定的范围以及 step 设定的步长，生成一个 ndarray。<br>\n",
    "numpy.linspace 函数用于创建一个一维数组，数组是一个等差数列构成的，格式如下：<br>\n",
    "```python\n",
    "np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)\n",
    "```\n",
    "两者之间的格式有区别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "bb60a33a-8cbd-4e41-bcf2-7dfdf54a3f8d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7 8 9]\n",
      "[ 1.          1.18367347  1.36734694  1.55102041  1.73469388  1.91836735\n",
      "  2.10204082  2.28571429  2.46938776  2.65306122  2.83673469  3.02040816\n",
      "  3.20408163  3.3877551   3.57142857  3.75510204  3.93877551  4.12244898\n",
      "  4.30612245  4.48979592  4.67346939  4.85714286  5.04081633  5.2244898\n",
      "  5.40816327  5.59183673  5.7755102   5.95918367  6.14285714  6.32653061\n",
      "  6.51020408  6.69387755  6.87755102  7.06122449  7.24489796  7.42857143\n",
      "  7.6122449   7.79591837  7.97959184  8.16326531  8.34693878  8.53061224\n",
      "  8.71428571  8.89795918  9.08163265  9.26530612  9.44897959  9.63265306\n",
      "  9.81632653 10.        ]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np \n",
    "a=np.arange(10)\n",
    "b=np.arange(1,10,2)\n",
    "c=np.linspace(1,10)\n",
    "print(a)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "29402a94-a11e-4078-87d2-78a3ef90d64b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0. 0. 0.]\n",
      " [0. 0. 0.]]\n",
      "[[1. 1. 1.]\n",
      " [1. 1. 1.]]\n"
     ]
    }
   ],
   "source": [
    "#全部是0\n",
    "import numpy as np \n",
    "a = np.zeros((2,3))\n",
    "b = np.ones((2,3))\n",
    "print (a)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "aa12ff5f-5b22-4f11-bc56-c8485a5dfdf6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[[[1 2 3 4]]]]\n"
     ]
    }
   ],
   "source": [
    "# 最小维度  \n",
    "import numpy as np \n",
    "a = np.array([1,2,3,4], ndmin = 2)  \n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f73cd581-1bf0-47aa-9c16-f9b60b6f476a",
   "metadata": {},
   "source": [
    "### 使用dtype来指定数据类型对象\n",
    "numpy支持的数据类型非常多。\n",
    "一般常用的有 float, int,str <br>\n",
    "全部数据类型可以参考 https://numpy.org/doc/stable/reference/arrays.dtypes.html<br>\n",
    "其中很多涉及到内存如何分配。需要结合c语言中的相关知识，目前可以不用花很多时间研究"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "089dda8a-b647-4a17-a9c6-6cf6733160ac",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.+0.j 2.+0.j 3.+0.j]\n"
     ]
    }
   ],
   "source": [
    "# dtype 参数  \n",
    "import numpy as np \n",
    "a = np.array([1,  2,  3],dtype=int)  \n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc099b31-c7b0-4fa3-8b84-ec5308f44e49",
   "metadata": {},
   "source": [
    "### 数组属性\n",
    "- rank 表示数组的维数（ndim），也就是数组“有几层方括号”。\n",
    "- axis 表示沿着哪个轴（方向）进行运算。它决定了 NumPy 在“求和、平均、最大值”等函数中如何聚合数据\n",
    "  - 行 (axis=0) ↓\n",
    "  - 列 (axis=1) →"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "89a41d14-ef7b-4fff-bc3a-df8db84606e0",
   "metadata": {},
   "source": [
    "#### ndarray.ndim\n",
    "ndarray.ndim 用于获取数组的维度数量（即数组的轴数）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "e76bfcfc-c55a-45fd-9046-44de5bc646ec",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "[[[1]\n",
      "  [2]]\n",
      "\n",
      " [[3]\n",
      "  [4]]]\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "import numpy as np \n",
    " \n",
    "a = np.array(3)\n",
    "b = np.array([1, 2, 3])\n",
    "c = np.array([[1, 2, 3], [4, 5, 6]])\n",
    "d = np.array([[[1], [2]], [[3], [4]]])\n",
    "\n",
    "print(a.ndim)  # 0维，标量\n",
    "print(b.ndim)  # 1维，向量\n",
    "print(c.ndim)  # 2维，矩阵\n",
    "print(d.ndim)# 3维，立体数组 \n",
    "# 现在调整其大小\n",
    "d.reshape(1,1,4) \n",
    "print(d)\n",
    "print (d.ndim)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63402ff3-36a5-4723-b424-e86c75c199a5",
   "metadata": {},
   "source": [
    "#### ndarray.shape\n",
    "ndarray.shape 表示数组的维度，返回一个元组，这个元组的长度就是维度的数目,即 ndim 属性(秩)。比如，一个二维数组，其维度表示\"行数\"和\"列数\"。<br>\n",
    "ndarray.reshape 也可以用于调整数组大小。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "968e4c86-e97f-4646-9e63-4bb2d1148657",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 3)\n",
      "[[1 2]\n",
      " [3 4]\n",
      " [5 6]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np  \n",
    " \n",
    "a = np.array([[1,2,3],\n",
    "              [4,5,6]])  \n",
    "print (a.shape)\n",
    "b=a.reshape(3,2) \n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "935fecb6-164d-4c47-a707-a14bc756e82b",
   "metadata": {},
   "source": [
    "注意：ndarray.reshape 通常返回的是非拷贝副本，即改变返回后数组的元素，原数组对应元素的值也会改变。\n",
    "```python\n",
    "import numpy as np  \n",
    "a = np.array([[1,2,3],\n",
    "              [4,5,6]])  \n",
    "b=a.reshape(3,2) \n",
    "b[0]=100\n",
    "print(a)\n",
    "```\n",
    "输出应该是多少？"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c43cff8c-9026-45a1-a85a-c10617110f09",
   "metadata": {},
   "source": [
    "### 从已有的数组创建数组\n",
    "\n",
    "#### numpy.asarray\n",
    "numpy.asarray 类似 numpy.array，但是numpy.array默认创建一个副本，修改不会改变原有对象，而numpy.asarray在原有对象上修改。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "cf0f81ee-f437-41b6-9c2c-b305a937936e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "b=[5. 1. 1.]\n",
      "x=[1. 1. 1.]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np \n",
    " \n",
    "x =  np.ones(3) \n",
    "#a = np.asarray(x) \n",
    "#a[0]=5\n",
    "#print(f\"a={a}\")\n",
    "\n",
    "b = np.array(x)\n",
    "b[0]=5\n",
    "print(f\"b={b}\")\n",
    "print(f\"x={x}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b1dba02-0609-44e5-801f-19c1c95fe7da",
   "metadata": {},
   "source": [
    "## NumPy 切片和索引"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51c3c31e-c3ad-453f-a0d8-3f8f0e1f9dfb",
   "metadata": {},
   "source": [
    "### slice函数切片（用的不是很多）\n",
    "通过内置的 slice 函数，并设置 start, stop 及 step 参数进行，从原数组中切割出一个新数组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "c792cdba-f2e1-41a6-abc5-5e03c6bcbb93",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2 4 6]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(10)\n",
    "s = slice(2,7,2)   # 从索引 2 开始到索引 7 停止，间隔为2\n",
    "print (a[s])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f25281c1-470a-4d41-a27e-106da58f295f",
   "metadata": {},
   "source": [
    "### 冒号分隔切片 \n",
    "[start:stop:step]\n",
    "冒号 : 的解释：如果只放置一个参数，如 [2]，将返回与该索引相对应的单个元素。如果为 [2:]，表示从该索引开始以后的所有项都将被提取。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "2de3dc98-478e-43dc-98f5-c2d861717092",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7 8 9]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(10)\n",
    "print(a[::])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4638cc08-dd6e-4f63-b4fc-388ab64b29e4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.array([[1,2,3],[3,4,5],[4,5,6]])\n",
    "print(a)\n",
    "# 从某个索引处开始切割\n",
    "print('从数组索引 a[1:] 处开始切割')\n",
    "print(a[1:])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b844fe0-a70c-4242-8453-a407e6273201",
   "metadata": {},
   "source": [
    "### 逗号分隔切片(用的很多)\n",
    "[行,列]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "f2e375ef-2eeb-44bd-a99d-b0e113201fb3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n",
      "20\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "arr = np.array([[10, 20, 30],\n",
    "                [40, 50, 60],\n",
    "                [70, 80, 90]])\n",
    "\n",
    "print(arr[0, 1])  # 第一行第二列，numpy更推荐这种\n",
    "print(arr[0][1])  #等价"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "401dfa4d-94c8-4b80-a394-be7a1ffa734d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[20 30]\n",
      " [50 60]]\n"
     ]
    }
   ],
   "source": [
    "print(arr[0:2,1:3])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c5a5043-ebf5-4ef6-a428-e23adeb45294",
   "metadata": {},
   "source": [
    "- 0:2 → 取前两行\n",
    "- 1:3 → 取第 2、3 列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "f0b152fb-10c9-46ea-a55c-f33cb857575e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[10 30]\n",
      " [70 90]]\n"
     ]
    }
   ],
   "source": [
    "print(arr[::2,::2])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd07f005-0a87-4103-a2b0-a429a618d377",
   "metadata": {},
   "source": [
    "- 行步长为 2 → 取第 0、2 行\n",
    "- 列步长为 2 → 取第 0、2 列"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65bf5450-27fd-4dc3-ae64-9fd9fd4c820b",
   "metadata": {},
   "source": [
    "#### 练习"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "2e1f85e3-c559-426a-a16a-b51b36ff9159",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3  4]\n",
      " [ 5  6  7  8]\n",
      " [ 9 10 11 12]\n",
      " [13 14 15 16]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "arr = np.arange(1, 17).reshape(4, 4)\n",
    "print(arr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "481b3736-7f11-4fc7-a978-af454053a765",
   "metadata": {},
   "source": [
    "1. 取出第 2 行第 3 列的元素\n",
    "2. 取出前两行、后两列的子矩阵\n",
    "3. 取出所有偶数行的第 1 列\n",
    "4. 使用逗号切片选出：\n",
    "```python\n",
    "[[6, 7],\n",
    " [10, 11]]\n",
    " ```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "176a27ed-1307-476b-9234-50ea67c65cd6",
   "metadata": {},
   "source": [
    "切片还可以包括省略号 …，来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号，它将返回包含行中元素的 ndarray。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "c3274d2b-2451-41bf-964c-0dc451ee9af2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2 4 5]\n",
      "[3 4 5]\n",
      "[[2 3]\n",
      " [4 5]\n",
      " [5 6]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.array([[1,2,3],[3,4,5],[4,5,6]])  \n",
    "print (a[...,1])   # 第2列元素\n",
    "print (a[1,...])   # 第2行元素\n",
    "print (a[...,1:])  # 第2列及剩下的所有元素\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5da0aa27-5831-4f2e-9b55-881b45a671a5",
   "metadata": {},
   "source": [
    "| **写法**       | **等价形式**   | **说明**                            |\n",
    "| -------------- | -------------- | ----------------------------------- |\n",
    "| arr[0, ...]    | arr[0, :, :]   | 选取第 0 个元素后，保留后面所有维度 |\n",
    "| arr[..., 0]    | arr[:, :, 0]   | 选取最后一维的第 0 个元素           |\n",
    "| arr[..., 1:3]  | arr[:, :, 1:3] | 对最后一维做切片                    |\n",
    "| arr[1, ..., 2] | arr[1, :, 2]   | 选取特定行和列的组合                |\n",
    "| arr[...]       | arr[:, :, :]   | 选取整个数组（相当于复制一份引用）  |\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f9c06469-1f75-4e89-8fcb-7815e1c370d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "print (a[1,...,2 ]) #输出是几"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "176b8e6e-fdea-4b79-b9c4-81c618e7c229",
   "metadata": {},
   "source": [
    "#### 练习：\n",
    "创建随机数组 img = np.random.rand(128, 128, 3)\n",
    "- 提取绿色通道（第二个通道）\n",
    "- 提取蓝色通道（最后一个通道）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e773313-a181-4ffb-b47e-7c140570be57",
   "metadata": {},
   "source": [
    "## NumPy 广播(Broadcast)\n",
    "广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式， 对数组的算术运算通常在相应的元素上进行。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "d4acf979-7bff-44cd-a915-e6660389558c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 10  40  90 160]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np \n",
    " \n",
    "a = np.array([1,2,3,4]) \n",
    "b = np.array([10,20,30,40]) \n",
    "c = a * b \n",
    "print (c)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6b0c331-0a5a-4652-89d4-ebb29b59e5ac",
   "metadata": {},
   "source": [
    "当运算中的 2 个数组的形状不同时，numpy 将自动触发广播机制。如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "b1b09e63-e5a1-465b-833a-8f3c161cf641",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0  1  2]\n",
      " [10 11 12]\n",
      " [20 21 22]\n",
      " [30 31 32]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np \n",
    " \n",
    "a = np.array([[ 0, 0, 0],\n",
    "           [10,10,10],\n",
    "           [20,20,20],\n",
    "           [30,30,30]])\n",
    "b = np.array([0,1,2])\n",
    "print(a + b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ece18a2-53a1-4716-aa7a-7a80df50a541",
   "metadata": {},
   "source": [
    "## NumPy 统计函数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c77a19ea-a7dc-42b7-bc7c-d22323122523",
   "metadata": {},
   "source": [
    "### numpy.mean()\n",
    "numpy.mean() 函数返回数组中元素的算术平均值，如果提供了轴，则沿其计算。<br>\n",
    "算术平均值是沿轴的元素的总和除以元素的数量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "c793471c-3e23-4e01-b49a-f717d6756e22",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我们的数组是：\n",
      "[[1 2 3]\n",
      " [3 4 5]\n",
      " [4 5 6]]\n",
      "\n",
      "\n",
      "调用 mean() 函数：\n",
      "3.6666666666666665\n",
      "\n",
      "\n",
      "沿轴 0 调用 mean() 函数：\n",
      "[2.66666667 3.66666667 4.66666667]\n",
      "\n",
      "\n",
      "沿轴 1 调用 mean() 函数：\n",
      "[2. 4. 5.]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np \n",
    " \n",
    "a = np.array([[1,2,3],[3,4,5],[4,5,6]])  \n",
    "print ('我们的数组是：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    "print ('调用 mean() 函数：')\n",
    "print (np.mean(a))\n",
    "print ('\\n')\n",
    "print ('沿轴 0 调用 mean() 函数：')\n",
    "print (np.mean(a, axis =  0))\n",
    "print ('\\n')\n",
    "print ('沿轴 1 调用 mean() 函数：')\n",
    "print (np.mean(a, axis =  1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32eb1c08-5e06-4f18-8f21-54275961837e",
   "metadata": {},
   "source": [
    "### numpy.average()\n",
    "numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。<br>\n",
    "该函数可以接受一个轴参数。 如果没有指定轴，则数组会被展开。<br>\n",
    "加权平均值即将各数值乘以相应的权数，然后加总求和得到总体值，再除以总的单位数。<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e69f50c-294d-4ff4-9646-89dc3f5169bf",
   "metadata": {},
   "source": [
    "考虑数组[1,2,3,4]和相应的权重[4,3,2,1]，<br>\n",
    "通过将相应元素的乘积相加，并将和除以权重的和，来计算加权平均值。<br>\n",
    "\n",
    "加权平均值 = (1x4+2x3+3x2+4x1)/(4+3+2+1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "6257a965-bfea-42eb-9a69-0639bf79bf28",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我们的数组是：\n",
      "[1 2 3 4]\n",
      "\n",
      "\n",
      "调用 average() 函数：\n",
      "2.5\n",
      "\n",
      "\n",
      "再次调用 average() 函数：\n",
      "2.0\n",
      "\n",
      "\n",
      "权重的和：\n",
      "(np.float64(2.0), np.float64(10.0))\n"
     ]
    }
   ],
   "source": [
    "import numpy as np \n",
    " \n",
    "a = np.array([1,2,3,4])  \n",
    "print ('我们的数组是：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    "print ('调用 average() 函数：')\n",
    "print (np.average(a))\n",
    "print ('\\n')\n",
    "# 不指定权重时相当于 mean 函数\n",
    "wts = np.array([4,3,2,1])  \n",
    "print ('再次调用 average() 函数：')\n",
    "print (np.average(a,weights = wts))\n",
    "print ('\\n')\n",
    "# 如果 returned 参数设为 true，则返回权重的和  \n",
    "print ('权重的和：')\n",
    "print (np.average([1,2,3,  4],weights =  [4,3,2,1], returned =  True))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e23f427-c41d-43a1-a672-16b3e80413f8",
   "metadata": {},
   "source": [
    "### numpy.std()和numpy.var()\n",
    "标准差是一组数据平均值分散程度的一种度量。<br>\n",
    "标准差是方差的算术平方根。<br>\n",
    "标准差公式如下：<br>\n",
    "std = sqrt(mean((x - x.mean())\\*2))<br>\n",
    "统计中的方差（样本方差）是每个样本值与全体样本值的平均数之差的平方值的平均数，<br>\n",
    "mean((x - x.mean())\\*\\* 2)。<br>\n",
    "换句话说，标准差是方差的平方根。<br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "339d38f4-b9da-4bf3-8997-38fd3d24baa8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.25\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    " \n",
    "print (np.var([1,2,3,4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68fe074b-39e5-46d1-a207-1774f4aaa309",
   "metadata": {},
   "source": [
    "### numpy.cov()\n",
    "计算协方差，返回一个矩阵<br>\n",
    "Cov( X, X )    Cov( X, Y )\n",
    "\n",
    "Cov( Y, X )    Cov( Y, Y )\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "d734044c-a4e1-40b7-8670-cc36d712ea7e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 2.5  5. ]\n",
      " [ 5.  10. ]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "x = np.array([1, 2, 3, 4, 5])\n",
    "y = np.array([2, 4, 6, 8, 10])\n",
    "\n",
    "cov = np.cov(x, y)\n",
    "print(cov)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fecd2f8f-16a1-4342-9341-7982739aca87",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
